home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 015 / scrnprt2.arc / LIB1.ASM next >
Assembly Source File  |  1985-06-22  |  17KB  |  632 lines

  1. ;  -Macro Library Number 1
  2. ;******************* LIB1.ASM  : Last Update: 2-8-85     **********
  3. ;
  4. ;                      MACROS AVAILABLE:
  5. ;------------------------------------------------------------------
  6.  
  7. ;  BINARY_TO_DISPLAY  MACRO   SOURCE, DEST
  8.            ;Convert 16-bit binary SOURCE to ASCII string: DEST.
  9.  
  10. ;  CCALL   MACRO   COND,PROCNAME
  11.            ;Conditional call macro
  12.  
  13. ;  CLS       MACRO  
  14.            ;Scroll screen down
  15.  
  16. ;  DISPLAY MACRO    TEXT
  17.            ;Display from offset TEXT until '$' terminator.
  18.  
  19. ;  DISP_AT MACRO  ROW,COLUMN,TEXT
  20.            ;Locate cursor and display from offset TEXT 
  21.            ;until '$' terminator.
  22.  
  23. ;  DISPCHAR MACRO    CHAR
  24.            ;Display a single ASCII character, advance cursor.
  25.  
  26. ;  FILE_ERRMSG                          
  27.            ;list of error messages for file I/O
  28.  
  29. ;  FILL_SCREEN    MACRO    CHAR,ATTRIBUTE,COUNT
  30.            ;Fill memory-mapped screen with char, attribute.
  31.            ;COUNT defaults to 2078, entire screen.
  32.  
  33. ;  INKEY   MACRO 
  34.            ;Input a single keystroke, returned in AH:AL
  35.  
  36. ;  INPUT BUFFER,COUNT
  37.      ; Input a string from the keyboard, terminated by a 0.
  38.  
  39. ;  KYBD_BINB MACRO      DEST_BYTE
  40.        ;Accepts input byte (0-255) from keyboard, and converts
  41.            ;to binary in DEST_BYTE
  42.  
  43. ;  LOCATE  MACRO ROW,COLUMN
  44.            ;Locate cursor at ROW, COLUMN
  45.  
  46. ;  SCROLL_WINDOW  MACRO ULR,ULC,LRR,LRC,ATTRIB
  47.  
  48. ;  SCROLLDN  MACRO  ULR,ULC,LRR,LRC 
  49.        ;Scroll screen down 1 line
  50.  
  51. ;  SCROLLUP  MACRO  ULR,ULC,LRR,LRC
  52.            ;Scroll screen up 1 line
  53.  
  54. ;  SETDATA MACRO DATASEG           
  55.            ;For .EXE files only: Start of Data Segment passed
  56.  
  57. ;  SHAPE  MACRO     TABLE, ROW, COLUMN
  58.   ;  This Macro prints a shape on the screen made up of ASCII 
  59.   ;  graphics characters.  TABLE is the offset of the shape table.
  60.   ;  If ROW, COL omitted, the shape starts at 12,40.
  61.   ;  Shape Table format: 
  62.   ;      1     Character to plot
  63.   ;      1      Attribute
  64.   ;      1      Row offset from last character
  65.   ;      1      Column offset from last character
  66.  
  67. ;  WINDOW  MACRO   ULR,ULC,LRR,LRC
  68.            ;Print window on screen, giving corner coordinates
  69.  
  70. ;  WRITESTR  macro
  71.            ;This displays a string terminated by 00H
  72.  
  73.  
  74. ; //////////////////////////////////////////////////////////////////
  75. ; \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  76.  
  77.  
  78.  
  79.  
  80. ;------------------------ FILE_ERRMSG -----------------------
  81. ;  This is a list of error messages in the FILE_IO library
  82. ;
  83. ;
  84.  
  85. file_errmsg    macro
  86.                 ; (address table of messages)
  87.   emess    dw    m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14
  88.     dw    m15,m16,m17,m18
  89.   m1    db    cr,lf,'Invalid function number',cr,lf,0
  90.   m2    db    cr,lf,'File not found',cr,lf,0
  91.   m3    db    cr,lf,'Path not found',cr,lf,0
  92.   m4    db    cr,lf,'Too many open files',cr,lf,0
  93.   m5    db    cr,lf,'Access denied',cr,lf,0
  94.   m6    db    cr,lf,'Invalid handle',cr,lf,0
  95.   m7    db    cr,lf,'Memory control blocks destroyed',cr,lf,0
  96.   m8    db    cr,lf,'Insufficient memory',cr,lf,0
  97.   m9    db    cr,lf,'Invalid memory block address',cr,lf,0
  98.   m10    db    cr,lf,'Invalid environment',cr,lf,0
  99.   m11    db    cr,lf,'Invalid format',cr,lf,0
  100.   m12    db    cr,lf,'Invalid access code',cr,lf,0
  101.   m13    db    cr,lf,'Invalid data',cr,lf,0
  102.   m14    db    cr,lf,'Message not in use',cr,lf,0
  103.   m15    db    cr,lf,'Invalid drive was specified',cr,lf,0
  104.   m16    db    cr,lf,'Attempted to remove the current directory',cr,lf,0
  105.   m17    db    cr,lf,'Not same device',cr,lf,0
  106.   m18    db    cr,lf,'No more files',cr,lf,0
  107. endm        ;----- end of macro ------
  108.  
  109.  
  110. ;-------------------------------------------------------
  111. ; INPUT  (buffer, length)
  112. ; This macro accepts input from the keyboard, storing
  113. ; the result at Buffer+2.  The length count causes a 
  114. ; row of periods (.) to display the length of the field.
  115.  
  116. input    macro    buffer,length
  117.     local    dot, display_input_field, crlf, start
  118.     jmp    start
  119. crlf    DB    0dH,0aH,0
  120.  start:    push    ax
  121.     push    bx
  122.     push    cx
  123.     push    dx
  124.     push    di
  125. display_input_field:
  126.     xor    bh,bh        ; video page zero
  127.     mov    cx,length    ; display a row of periods (.)
  128.     mov    al,'.'
  129.     mov    ah,0AH        ; display multiple characters
  130.     int    10H        ; bios INT 10H video function
  131.  
  132.     mov    al,0        ; fill buffer with zeros
  133.     lea    di,buffer
  134.     mov    cx,length + 1    ; one extra for CR at eol
  135.  repnz    stosb    
  136.     mov    ah,0AH        ; keyboard input
  137.     mov    buffer,length+1    ; put max length at head
  138.     mov    DX,offset buffer
  139.     int    21H
  140.     pop    di        ; restore all registers
  141.     pop    dx
  142.     pop    cx
  143.     pop    bx
  144.     pop    ax
  145.     writestr crlf        ; print a carriage return
  146.     endm
  147.  
  148.  
  149.  
  150. ;-----------------------------------------------------------
  151. ; This Macro prints a horizontal line, using the string
  152. ; pointed to by [DI] directly into the screen buffer.
  153. ; On entry:  DS:BX = offset of screen buffer location.
  154. ;-----------------------------------------------------------
  155. PRINT_LINE    MACRO    left,mid,right,len
  156.     local    m1
  157.     push    BX
  158.     push    CX
  159.     xor    CX,CX
  160.     mov    CL,len            ;use as a loop count
  161.  
  162.     mov    AL,left            ;1st char.
  163.      mov    [BX],AL            ;store in memory
  164.     add    BX,2            ;next screen location
  165.     mov    AL,mid
  166.  
  167.  m1:     mov    [BX],AL            ;store in memory
  168.     add    BX,2            ;next screen location
  169.     loop    m1
  170.  
  171.     mov    AL,right        ;last char.
  172.     mov    [BX],AL
  173.  
  174.     pop    CX
  175.     pop    BX
  176.     ENDM
  177.  
  178.  
  179. ;--------------------------------- WINDOW ---------------------
  180. ;  Draw window on screen, giving upper-left and lower-right
  181. ;  corners.
  182. ;--------------------------------------------------------------
  183. WINDOW    MACRO    ULR,ULC,LRR,LRC
  184.     local    top,mid,bot
  185.     push    AX
  186.     push    BX
  187.     push    CX
  188.     push    DS            ;save current DS value
  189.     mov    AX,0B000H
  190.     mov    DS,AX
  191.     mov    BX,(ULR-1)*160        ;BX points to screen buffer
  192.     add    BX,(ULC-1)*2    
  193.     wid =    (LRC-ULC-1)        ;"width" is a reserved word
  194.     height = (LRR-ULR-1)
  195.  top:    print_line 0C9H,0CDH,0BBH,wid
  196.     xor    CX,CX
  197.     mov    CL,height
  198.  mid:    add    BX,160            ;next line in screen buffer
  199.     print_line  0BAH,20H,0BAH,wid
  200.     loop    mid
  201.  
  202.  bot:    add    BX,160    
  203.     print_line  0CAH,0CDH,0BCH,wid
  204.     pop    DS            ;retrieve DS register
  205.     pop    CX
  206.     pop    BX
  207.     pop    AX
  208.     ENDM
  209.  
  210.  
  211. ;-----------------------  INKEY --------------------------------
  212. ; Get keystroke, place in AL.
  213. ; On exit:   AH=1, AL=key for normal keys.
  214. ;            For extended codes, AH=FF, AL=extended code.
  215. ;---------------------------------------------------------------
  216. INKEY   MACRO   CHAR
  217.     local    norm,ext,done
  218.     mov    AH,7        ;read kybd, no echo
  219.     int    21H
  220.     or    AL,AL        ;extended code?
  221.     jz    ext
  222.  
  223.   norm:    mov    AH,1        ;signal normal ASCII char.
  224.     jmp    done        ;and exit
  225.    ext:    int    21H        ;read 2nd character of extended code
  226.     mov    AH,0FFH        ;signal extended code
  227. done:   nop
  228.     endm
  229.  
  230.  
  231. ;----------------  BINARY_TO_DISPLAY -----------------------
  232. ;  On entry:  Source = 16-bit signed binary value
  233. ;             Dest   = ASCII result string
  234. ;------------------------------------------------------------
  235. BINARY_TO_DISPLAY  MACRO   SOURCE, DEST
  236.     local   fill,clr_dvd,exit_binary_to_display
  237.     push    AX
  238.     push    BX
  239.     push    CX
  240.     push    DX
  241.     push    SI
  242.  
  243.     mov    AX,SOURCE    ;original Binary number
  244.     push    AX        ;preserve the number
  245.     mov    BX,OFFSET DEST    ;offset of ASCII string
  246.     mov    CX,6        ;6 digits = max. length
  247.  
  248.   fill:    mov    byte ptr [BX],' '    ;fill with blanks
  249.     inc    BX
  250.     loop    fill
  251.  
  252.     mov    SI,10        ;will divide by 10
  253.     or    AX,AX
  254.     jns    clr_dvd        ;negative?
  255.     neg    AX        ;yes- make it positive
  256.  
  257.   clr_dvd:
  258.     xor    DX,DX
  259.     div    SI        ;divide AX by 10 (rem. in DX)
  260.     add    DX,30H        ;convert remainder to ASCII
  261.     dec    BX        ;reverse thru ascii_result
  262.     mov    [BX],DL        ;store ASCII character
  263.     inc    CX        ;count length of string
  264.     or    AX,AX        ;AX = 0?
  265.     jnz    clr_dvd        ;no - divide again
  266.  
  267.     pop    AX        ;yes -retrieve original number
  268.     or    AX,AX        ;was it negative?
  269.     jns    exit_binary_to_display
  270.  
  271.     dec    BX        ;yes - store a "-" sign
  272.     mov    byte ptr [BX],'-'
  273.     inc    CX
  274.  
  275.  exit_binary_to_display:        ;(AX was popped)
  276.     pop    SI
  277.     pop    DX
  278.     pop    CX
  279.     pop    BX
  280.     pop    AX
  281.     ENDM
  282.  
  283.  
  284. ;   (SCROLL_WINDOW)
  285. ;   Parameters: Upper Left Row, Upper left column, Lower right row,
  286. ;   Lower right column, Num lines to clear, Attribute of blank lines
  287. ;   Entire screen cleared if all parameters omitted.
  288.  
  289. Scroll_window    MACRO    ULR,ULC,LRR,LRC,LINES,ATTRIB 
  290.     PUSH    AX
  291.     PUSH    BX
  292.     PUSH    CX
  293.     PUSH    DX
  294.     MOV    AH,7        ;Scroll down function
  295.     
  296.     MOV    AL,LINES    ;Num lines to scroll
  297.     IFB    <LINES>        ;If LINES omitted, scroll entire
  298.       MOV    AL,0        ;  window.
  299.     ENDIF
  300.     
  301.     MOV    CH,ULR        ;Upper left row
  302.     MOV    CL,ULC        ;Upper left column
  303.     IFB    <ULC>        ;If upper left omitted, choose
  304.       MOV    CX,0        ;  0,0 as upper left corner.
  305.     ENDIF
  306.     
  307.     MOV    DH,LRR        ;Lower right row
  308.     MOV    DL,LRC        ;Lower right column
  309.     IFB    <LRC>        ;If lower right omitted, choose
  310.       MOV    DX,184FH    ;  24,79 as lower right corner.
  311.     ENDIF
  312.  
  313.     MOV    BH,ATTRIB    ;Attribute of blank lines
  314.     IFB    <ATTRIB>    ;If attribute omitted, choose
  315.       MOV    BH,7        ;  normal attribute
  316.     ENDIF
  317.  
  318.     INT    10H        ;Call BIOS to do the job
  319.     POP    DX        ;Restore scratch registers
  320.     POP    CX
  321.     POP    BX
  322.     POP    AX
  323.     ENDM
  324.  
  325. ;--------------------------  CLS  ----------------------------------
  326. ;  Clears the entire screen
  327. ;
  328. Cls    MACRO
  329.     PUSH    AX
  330.     PUSH    BX
  331.     PUSH    CX
  332.     PUSH    DX
  333.     MOV    AH,7        ;  Scroll down function
  334.      MOV    AL,0        ;  0 = entire window
  335.       MOV    CX,0        ;  0,0 as upper left corner.
  336.     MOV    DX,184FH    ;  24,79 as lower right corner.
  337.     MOV    BH,7        ;  normal attribute
  338.     INT    10H        ;  Call BIOS 
  339.     POP    DX        ;  Restore scratch registers
  340.     POP    CX
  341.     POP    BX
  342.     POP    AX
  343.     ENDM
  344.  
  345.  
  346. ;-------------------------- SCROLLUP ----------------------
  347. ;  Scroll window up one line.  All 4 parameters must be included.
  348. SCROLLUP  MACRO    ULR,ULC,LRR,LRC
  349.     PUSH    AX
  350.     PUSH    BX
  351.     PUSH    CX
  352.     PUSH    DX
  353.     MOV    AX,0601H    ;Scroll up one line
  354.     MOV    CH,ULR        ;Upper left row
  355.     MOV    CL,ULC        ;Upper left column
  356.     MOV    DH,LRR        ;Lower right row
  357.     MOV    DL,LRC        ;Lower right column
  358.     MOV    BH,7        ;  normal attribute
  359.     INT    10H        ;Call BIOS to do the job
  360.     POP    DX        ;Restore scratch registers
  361.     POP    CX
  362.     POP    BX
  363.     POP    AX
  364.     ENDM
  365.  
  366.  
  367.  
  368. ;-------------------------- SCROLLDN ----------------------
  369. ;  Scroll window donw one line.  All 4 parameters must be 
  370. ;  included.
  371. SCROLLDN  MACRO    ULR,ULC,LRR,LRC
  372.     PUSH    AX
  373.     PUSH    BX
  374.     PUSH    CX
  375.     PUSH    DX
  376.     MOV    AX,0701H    ;Scroll down one line
  377.     MOV    CH,ULR        ;Upper left row
  378.     MOV    CL,ULC        ;Upper left column
  379.     MOV    DH,LRR        ;Lower right row
  380.     MOV    DL,LRC        ;Lower right column
  381.     MOV    BH,7        ;  normal attribute
  382.     INT    10H        ;Call BIOS to do the job
  383.     POP    DX        ;Restore scratch registers
  384.     POP    CX
  385.     POP    BX
  386.     POP    AX
  387.     ENDM
  388.  
  389.  
  390. ;---------------------------  LOCATE  -----------------------
  391.  
  392. LOCATE    MACRO ROW,COLUMN
  393.         PUSH AX
  394.     PUSH BX
  395.         PUSH DX
  396.     XOR  BX,BX        ;New: added 4-30-84, since the BX
  397.                 ;  register must be cleared to 0 for
  398.                 ;  the Interrupt to work correctly.
  399.     MOV  AH,2        ;Function selected = locate
  400.         MOV  DH,ROW
  401.         MOV  DL,COLUMN
  402.         INT  10H                ;Invoke BIOS to position cursor
  403.         POP DX
  404.     POP BX
  405.         POP AX
  406.     ENDM
  407.  
  408.  
  409. ;---------------------------- CCALL MACRO ------------------------
  410. ccall    macro    cond,procname
  411.     Local    L1,L2
  412.     J&cond    L1
  413.     jmp    L2
  414.   L1:   call    procname
  415.   L2:   exitm
  416.         endm
  417.  
  418. ;-------------------------  DISPLAY  -------------------------
  419.  
  420. DISPLAY MACRO    TEXT            ;'TEXT' is a passed parameter
  421.         PUSH AX
  422.         PUSH DX
  423.         MOV  AH,9               ;Function selected-console output
  424.     MOV  DX,OFFSET TEXT    ;Point to message to print
  425.         INT  21H                ;Request DOS service, ID in AH
  426.         POP DX
  427.         POP AX
  428.     ENDM
  429.  
  430.  
  431.  
  432. ;-----------------------  DISP_AT  ---------------------------
  433. ;  This Macro combines LOCATE and DISPLAY.  If ROW and COLUMN
  434. ;  are omitted, then 0,0 is assumed, but the leading commas
  435. ;  must be supplied:  DISP_AT  ,,MSG1   (example)
  436.  
  437. DISP_AT MACRO    ROW,COLUMN,TEXT
  438.         PUSH     AX
  439.     PUSH     BX
  440.         PUSH     DX
  441.     XOR      BX,BX
  442.     MOV      AH,2        ;Function selected = locate
  443.         MOV      DH,ROW
  444.     IFB     <ROW>
  445.       MOV    DH,0
  446.     ENDIF
  447.         MOV      DL,COLUMN
  448.     IFB    <COLUMN>
  449.       MOV    DL,0
  450.     ENDIF
  451.         INT      10H             ;Invoke BIOS to position cursor
  452.         MOV       DX,OFFSET TEXT  ;Offset from DS:
  453.         MOV       AH,9        ;Select console output function
  454.         INT       21H             ;Request DOS service
  455.         POP       DX
  456.     POP    BX
  457.     POP    AX
  458.         ENDM
  459.  
  460.  
  461.  
  462. SETDATA MACRO DATASEG           ;Start of Data Segment passed
  463.         PUSH  DS                ;Return addr of data seg on stack
  464.         MOV   AX,0
  465.         PUSH  AX                ;Put zero offset return addr. on stack
  466.         MOV   AX,DATASEG        ;Initialize data segment
  467.         MOV   DS,AX
  468.         ENDM
  469. ;
  470. DISPCHAR MACRO    CHAR
  471.     PUSH    DX
  472.     PUSH    AX
  473.     MOV    DL,CHAR        ;CHAR. TO BE PRINTED
  474.     MOV    AH,02H        ;REQUEST SINGLE CHAR. OUTPUT
  475.     INT    21H
  476.     POP    AX
  477.     POP    DX
  478.     ENDM
  479.  
  480.  
  481.  
  482. ;-----------------------  FILL_SCREEN  --------------------------
  483. ;  This Macro fills the screen with the ASCII code CHAR (0-255).
  484. ;  ATTRIBUTE may be any of the following: normal (07H), normal w/
  485. ;  high intensity (0FH), reverse (70H), reverse w/ high intensity
  486. ;  (78H), normal+blink (87H), reverse+blink (F8H).  See Scanlon
  487. ;  text, p.251.  If ATTRIBUTE omitted, normal is assumed.  If 
  488. ;  COUNT omitted, then 2078 assumed.
  489.  
  490. FILL_SCREEN    MACRO    CHAR,ATTRIBUTE,COUNT
  491.     PUSH    AX            ;Save all scratch registers
  492.     PUSH    CX
  493.     PUSH    DX
  494.     PUSH    DI
  495.     PUSH    DS
  496.     MOV    CX,COUNT        ;Number of mem locations
  497.     IFB <COUNT>            ;If COUNT is blank, set it
  498.       MOV   CX,2078            ;  to 2078 (full screen).
  499.     ENDIF
  500.     MOV    DH,CHAR            ;ASCII code to be output
  501.     MOV    DL,ATTRIBUTE        ;Attribute byte
  502.     IFB     <ATTRIBUTE>        ;If ATTRIBUTE is blank, set
  503.       MOV   DL,0FH            ;  to 0F - normal display.
  504.     ENDIF
  505.     XOR    DI,DI
  506.     MOV    AX,0B000H        ;Addr of text display card
  507.     MOV    DS,AX            ;Put screen addr in DS
  508. STORE_CHAR:
  509. MOV    [DI],DH                ;Store character
  510.     INC    DI            ;Point to attribute byte
  511.     MOV    [DI],DL            ;Store the attribute
  512.     INC    DI
  513.     LOOP    STORE_CHAR        ;Continue until CX=0
  514.     POP    DS
  515.     POP    DI            ;Restore all registers
  516.     POP    DX
  517.     POP    CX
  518.     POP    AX
  519.     ENDM
  520.  
  521.  
  522. ;---------------------- KYBD_BINB -----------------------------
  523. ;  This macro accepts any integer from the keyboard from 0-255,
  524. ;  and stores it at DEST_BYTE in binary.  If a larger number is
  525. ;  desired, use the KYBD_BINW Macro (0-65535).
  526. ;--------------------------------------------------------------
  527.     KYBD_BINB MACRO      DEST_BYTE
  528.     PUSH    AX
  529.     PUSH    BX
  530.     PUSH    CX
  531.     MOV    BX,0        ;BX will accumulate the digits
  532. NEWCHAR:
  533.     MOV    AH,1        ;DOS function for keyboard input
  534.     INT    21H
  535.     SUB    AL,30H        ;Convert the digit to Binary
  536.     JL    EXIT_BINW    ;Exit if value < 0
  537.     CMP    AL,9        ;Is the digit > 9?
  538.     JG    EXIT_BINW    ;Yes.  Must not be a decimal digit
  539.     CBW            ;Convert byte in AL to word in AX
  540.     XCHG    AX,BX        ;Exch input digit & amount so far
  541.     MOV    CX,10D
  542.     MUL    CX        ;Multiply amt collected by 10
  543.     XCHG    AX,BX        ;Store back in BX register
  544.     ADD    BX,AX        ;Add current digit to existing amt
  545.     JMP    NEWCHAR        ;Get another keyboard char.
  546. EXIT_BINW:
  547.     MOV    [DEST_BYTE],BL    ;Store the result
  548.     POP    CX        ;Restore scratch registers
  549.     POP    BX
  550.     POP    AX
  551.     ENDM
  552.  
  553.  
  554. ;------------------------------------------------------
  555. ;              WRITESTR  macro
  556. ;
  557. ;  This displays a string terminated by 00H
  558. ;  String is an offset value.
  559. ;------------------------------------------------------
  560.  
  561. writestr    macro    string
  562.     local    again,exit
  563.     push    AX
  564.     push    BX
  565.     push    DX
  566.     mov    AH,2        ;single char output
  567.     mov    BX,offset string
  568.   again:
  569.     mov    DL,[BX]
  570.     cmp    DL,0        ;check for zero teminator
  571.     jz    exit
  572.     int    21H
  573.     inc    BX
  574.     jmp    again
  575.  
  576.   exit:    pop    DX
  577.     pop    BX
  578.     pop    AX
  579.  endm   ;--------------------------------------------
  580.  
  581.  
  582. ;-------------------------  SHAPE  ----------------------------
  583. SHAPE    MACRO    TABLE, ROW, COLUMN
  584. ;  This Macro prints a shape on the screen made up of ASCII 
  585. ;  graphics characters.  TABLE is the offset of the shape table,
  586. ;  ROW and COLUMN are the optional starting location.  If omitted,
  587. ;  the shape starts at 12,40.
  588. ;---------------------------------------------------------------
  589. SHAPE    MACRO    TABLE, ROW, COLUMN
  590.  
  591.     MOV    DI, OFFSET TABLE ;Point to start of table
  592.     MOV    DH, ROW
  593.     MOV    DL, COLUMN
  594.     IFB    <COLUMN>        ;If row & column omitted,
  595.           MOV    DX, 0C28H    ;Start at row 12, column 40
  596.     ENDIF
  597.     PUSH    AX        ;Save registers
  598.     PUSH    BX
  599.     PUSH    CX
  600.     PUSH    DX
  601.     PUSH    DI        ;Save pointer to start of table
  602.     STI            ;Enable interrrupts
  603.     MOV    AH,15        ;Set BH to active display page
  604.     INT    10H
  605.     SUB    CH,CH        ;Clear high byte of count
  606.     MOV    CL,[DI]        ;CL holds character count
  607.     INC    DI        ;DI points to first character
  608.  
  609. NEXT_CHAR:
  610.     ADD    DH,[DI+2]    ;Update row pointer relative from
  611.                 ; last position
  612.     ADD    DL,[DI+3]    ;Also column pointer
  613.     MOV    AH,2        ;Move cursor
  614.     INT    10H
  615.     MOV    AL,[DI]        ;Get ASCII code of character
  616.     MOV    BL,[DI+1]    ;  and attribute.
  617.     PUSH    CX        ;Save character count
  618.     MOV    CX,1        ;Write a single char. to screen
  619.     MOV    AH,9        ;Function #9 for INT 10H
  620.     INT    10H
  621.     POP    CX        ;Restore character count
  622.     ADD    DI,4        ;DI points to next character block
  623.     LOOP    NEXT_CHAR    ;Do another character until CX=0
  624.  
  625.     POP    DI        ;Restore all registers
  626.     POP    DX
  627.     POP    CX
  628.     POP    BX
  629.     POP    AX
  630.     ENDM
  631.  
  632.